#ifndef JSCRIPTEDIT_H
#define JSCRIPTEDIT_H

#include <QWidget>
#include <QTextEdit>
#include <QTextBlockUserData>

class JScriptEdit : public QTextEdit
{
	Q_OBJECT

public:
	JScriptEdit(QWidget *parent = NULL);
	~JScriptEdit();

public slots:
	void keyPressEvent(QKeyEvent *e);

private slots:
	void slotCursorPositionChanged();
	void slotViewportUpdate();

private:
	void braceMatching();
	void paintEvent(QPaintEvent *);
	
	int mTab;
};

class JScriptEditPanel : public QWidget
{
public:
	JScriptEditPanel(QWidget *p = 0): QWidget(p), pEdit(0) {}
	virtual ~JScriptEditPanel(){}

	QTextEdit * editor() {return pEdit;}
	void attach(QTextEdit *e);

protected:
	virtual void paintEvent(QPaintEvent *e);
	virtual void paint(QPainter *p, QTextEdit *e) = 0;

private:
	QTextEdit *pEdit;
};

struct QBlockData;
struct QFoldedText
{
	QFoldedText() {}

	~QFoldedText() { lines.clear(); }

	inline void addLine(QString b, QBlockData *t)
	{ lines << qMakePair(b, t); }

	QList< QPair<QString, QBlockData*> > lines;
};

struct QBlockData : public QTextBlockUserData
{
	inline QBlockData() :
	folded(0), collapsedBlock(0), marked(false)
	{}

	~QBlockData() { }

	static QBlockData* data(const QTextBlock& block)
	{ return dynamic_cast<QBlockData *>(block.userData()); }

	void setToBlock(QTextBlock & block)
	{ block.setUserData(this); }

	bool marked;
	QFoldedText *folded;
	int userState;
	int collapsedBlock;
};

class LineNumberPanel : public JScriptEditPanel
{
public:
	LineNumberPanel(QWidget *p = 0);
	virtual ~LineNumberPanel() {}

protected:
	virtual void paint(QPainter *p, QTextEdit *e);

private:

};

typedef enum _FoldType {
	FOLD_OFF = 0, 
	FOLD_SINGLELINECOMMENT, 
	FOLD_MULTILINECOMMENT,
	FOLD_STRING,
	FOLD_CHAR
} ;

class LineFoldPanel : public JScriptEditPanel
{
public:
	LineFoldPanel(QWidget *p = 0);
	virtual ~LineFoldPanel() {}

	void expand(QTextBlock & b);
	void expandAll();
	bool collapsed(QTextBlock & b);
	void mouseclk(QTextBlock & b);

protected:
	virtual void mousePressEvent(QMouseEvent *e);
	virtual void keyPressEvent(QKeyEvent *e);
	virtual void paint(QPainter *p, QTextEdit *e);

	QRect drawIcon(QPainter *p, QTextEdit *e, int x, int y, bool toExpand);
	void match(QTextEdit *e);
	void setBlockUserState(QTextBlock & b, int state);
	int BlockUserState(const QTextBlock & b);

private:
	_FoldType FoldType;
	QMap<QTextBlock, QRect> collapsable;
};

#endif // JSCRIPTEDIT_H
